/*******************************************************************************
 * Copyright 2011 @ Kapil Viren Ahuja
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.kapilvirenahuja.eamsteps.dataprovider;

import com.kapilvirenahuja.eamsteps.common.DataProviderException;
import com.kapilvirenahuja.eamsteps.datareader.IDataSet;
import com.kapilvirenahuja.eamsteps.datareader.IDataTable;
import com.kapilvirenahuja.eamsteps.form.IDataForm;

/**
 * Base implementation for {@link IDataProvider}. This class provides some common functionalities:
 * <ul>
 * <li>Store the form object that needs to store the data after processing is over</li>
 * <li>Stores the {@link IDataSet} object from which the data is to be read</li>
 * <li>Provides validation of the Form based on the underlying date provided by the {@link IDataSet}. If the Form does
 * not have all the needed Getters and Setters, then the processing is halted.</li>
 * </ul>
 * 
 */
public abstract class AbstractDataProvider implements IDataProvider
{
//    private static final ILogger logger = LogFactory.getInstance().getLogger(AbstractDataProvider.class);


    private IDataForm            form;
    private IDataSet             dataset;
    private Boolean              valid;


    /**
     * @see IDataProvider#getForm()
     * 
     */
    public IDataForm getForm()
    {
        return this.form;
    }


    /**
     * @see IDataProvider#getDataSet()
     * 
     */
    public IDataSet getDataSet()
    {
        return this.dataset;
    }


    /**
     * @see IDataProvider#setDataSet(IDataSet)
     */
    public void setDataSet(IDataSet dataSet)
    {
        this.dataset = dataSet;
    }


    /**
     * @see IDataProvider#isValid()
     * 
     */
    public Boolean isValid()
    {
        return this.valid;
    }


    /**
     * Only constructor to the class that requires an object of {@link IDataForm}. This constructor will also set the
     * validation status to <code>Boolean.FALSE</code>, which will force the implementations to ensure they run the
     * validation and update it to <code>Boolean.TRUE</code>.
     * 
     * 
     * @param form
     */
    public AbstractDataProvider(IDataForm form)
    {
        this.form = form;

        // Set the isValid to false as the default.
        this.valid = Boolean.FALSE;
    }


    /**
     * Default implementation for validating the Provider. It checkes for the following:
     * <ol>
     * <li>The instance of {@link IDataForm} should be initialized</li>
     * <li>The instance of the {@link IDataSet} should be initialized</li>
     * </ol>
     * 
     * If all the validations pass, this method will update the status for {@link IDataProvider#isValid()} to
     * <code>Boolean.TRUE</code>
     * 
     */
    public void validateForm()
    {
//        logger.info("Start global validations.");
        if (this.getForm() == null || this.getDataSet() == null)
        {
//            logger.error("Form and/or DataSet has not been initialized; initialization stopped");
            throw new DataProviderException("Form and/or DataSet have not been initialized.");
        }

        // If there are no exceptions, it means that the validations have passed.
        this.valid = Boolean.TRUE;
    }


    /**
     * This method should be implemented by the concrete implementation classes. It should hold the following logic:
     * <ol>
     * <li>Iterate over all the {@link IDataTable} provided in the {@link IDataSet}</li>
     * <li>Parse the header rows for each of {@link IDataTable}</li>
     * <li>Parse the data rows for each of {@link IDataTable}</li>
     * <li>Create Java Objects for each of rows in {@link IDataTable}</li>
     * <li>Add the initialized java objects to {@link IDataForm}</li>
     * </ol>
     * 
     * @param dataTable
     */
    protected abstract void parseRows(IDataTable dataTable);
}
